package eu.codlab.game.gameba;

import eu.codlab.androidemu.Emulator.FrameUpdateListener;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class EmulatorView extends SurfaceView
implements SurfaceHolder.Callback {

	public static final int SCALING_ORIGINAL = 0;
	public static final int SCALING_PROPORTIONAL = 1;
	public static final int SCALING_STRETCH = 2;
	private int actualWidth;
	private int actualHeight;
	private float aspectRatio;

	private Emulator emulator;
	private int scalingMode = SCALING_PROPORTIONAL;

	public EmulatorView(Context context, AttributeSet attrs) {
		super(context, attrs);

		final SurfaceHolder holder = getHolder();
		holder.setFormat(PixelFormat.RGB_565);
		holder.setFixedSize(Emulator.VIDEO_W, Emulator.VIDEO_H);
		holder.setKeepScreenOn(true);
		holder.addCallback(this);

		setFocusableInTouchMode(true);
		requestFocus();
	}

	public void setEmulator(Emulator e) {
		Log.d("EmulatorView","setEmulator");
		emulator = e;
	}

	public void setScalingMode(int mode) {
		if (scalingMode != mode) {
			scalingMode = mode;
		}
	}
	private int i=0;
	public void onImageUpdate(int[] data) {
		SurfaceHolder holder = getHolder();
		Canvas canvas = holder.lockCanvas();
		canvas.drawBitmap(data, 0, Emulator.VIDEO_W, 0, 0,
				Emulator.VIDEO_W, Emulator.VIDEO_H, false, null);
		holder.unlockCanvasAndPost(canvas);
		if(_waiting_screen == true){
			final Bitmap bitmap = Bitmap.createBitmap(data, 0, Emulator.VIDEO_W, Emulator.VIDEO_W, Emulator.VIDEO_H, Config.RGB_565);
			_waiting_screen = false;
			Thread t = new Thread(){
				public void run(){
					if(_callback_tmp != null){
						_callback_tmp.onScreenRefresh(bitmap);
						_callback_tmp = null;
					}
					if(bitmap != null && !bitmap.isRecycled())
						bitmap.recycle();
				}
			};
			t.start();
		}
	}

	private boolean _waiting_screen = false;
	private EmulatorViewCallback _callback_tmp;
	public void waitingScreenShotNextRefresh(EmulatorViewCallback callback){
		_callback_tmp = callback;
		_waiting_screen = true;
	}

	private OnFrameDrawnListener listener;
	public interface OnFrameDrawnListener {
		void onFrameDrawn(Canvas canvas);
	}

	public void setFrameUpdateListener(OnFrameDrawnListener l){
		listener = l;
	}

	public void surfaceCreated(SurfaceHolder holder) {
		i=0;
		//emulator.setRenderSurface(this, 0, 0);
	}

	public void surfaceDestroyed(SurfaceHolder holder) {
		emulator.setRenderSurface(null, 0, 0);
	}

	public void surfaceChanged(SurfaceHolder holder,
			int format, int width, int height) {
		emulator.setRenderSurface(this, width, height);
	}

	EmulatorViewControl _controlers;
	public void setSurroundControllers(EmulatorViewControl controllers){
		if(_controlers == null && controllers != null){
			_controlers = controllers;
			_controlers.setEmulatorView(this);
		}
	}

	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int specWidth = MeasureSpec.getSize(widthMeasureSpec);
		int specHeight = MeasureSpec.getSize(heightMeasureSpec);
		int w, h;

		if(_controlers != null){
			if(_controlers.getSpaceHeight() > _controlers.getSpaceWidth()){
				//Height > Width so 
				specHeight -= _controlers.getSpaceHeight();
			}else{
				specWidth -= _controlers.getSpaceWidth();
			}
		}

		switch (scalingMode) {
		case SCALING_ORIGINAL:
			w = Emulator.VIDEO_W;
			h = Emulator.VIDEO_H;
			break;
		case SCALING_STRETCH:
			if (specWidth >= specHeight) {
				w = specWidth;
				h = specHeight;
				break;
			}
			// fall through
		case SCALING_PROPORTIONAL:
			h = specHeight;
			w = h * Emulator.VIDEO_W / Emulator.VIDEO_H;
			if (w > specWidth) {
				w = specWidth;
				h = w * Emulator.VIDEO_H / Emulator.VIDEO_W;
			}
			break;
		default:
			super.onMeasure(widthMeasureSpec, heightMeasureSpec);
			return;
		}

		setMeasuredDimension(w, h);
	}
}
